#ifndef _FLOAT_H_
#define _FLOAT_H_
#define debug(x, y, z) 	cout << "Value of: " << x << " is: " << y << endl; cin >> z;  
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
/* Float class.  this is essentially a 
 * wrapper class for the double type, but 
 * the difference is in the functions == and raiseto. 
 * these allow you to raise to a variable type
 * and compare doubles that are close. 
 */ 

class Float {
	private:

		typedef unsigned long int ulint; //just to make less work for the fingers, I've got some typedefs here.
		typedef long int lint; 	
		static double precision; 
		static double precision_mult;
		static double equals_precision; 
	public: 
//vars 

		double value; 
//functions
		Float(); 
		Float(double); 
		~Float(); 

		static bool setprecision(double, double, double); 
		Float square(); 	
		Float raiseto(int);
		Float raiseto(double, double); 	
//operators - +=, -=, etc. these are all basically wrappers. 
		operator double();
		operator float();
		operator int(); 
		Float operator+  (const double); 
		Float operator+  (const Float); 
		Float operator+= (const double);
		Float operator+= (const Float);
		Float operator-  (const double); 
		Float operator-  (const Float); 
		Float operator-= (const double);   
		Float operator-= (const Float);
		Float operator*= (const double);
		Float operator*= (const Float);
		Float operator*  (const double);
		Float operator*  (const Float);  
		Float operator/  (const double);
		Float operator/= (const double);
		Float operator/  (const Float);
		Float operator/= (const Float);
	

		void operator++(int);
		void operator--(int); 
	 
		Float operator=  (const double); 
		Float operator=  (const Float);

		bool operator <= (const double) const;
		bool operator <= (const Float) const; 
		bool operator >= (const double) const;
		bool operator >= (const Float) const;
		bool operator >  (const double) const; 
		bool operator <  (const double) const; 
		bool operator >  (const Float) const; 
		bool operator <   (const Float) const; 

		template <class Type>
		bool operator== (const Type) const;  

		template <class Type>
		bool operator != (const Type) const;
}; 
template <class Type>
bool Float::operator== (const Type inval) const {
	
	
	try {
			Type in2 = inval;
			double in = static_cast<double>(in2); 
			if(*this <= (in + 0.0001) && *this >= (in - 0.0001) ) {
				return true; 
			} else {
		
				return false; 
			}
		} catch(...) {
			std::cerr << "Error while comparing two variables of type: " << typeid(Type).name() << "and Float" << std::endl;
			throw "Error comparing"; 
			return false; 
		} 
	 
} 

template <class Type>
bool Float::operator!=(const Type inval) const
{
	if(*this == inval) {
		return false;
	} else {
		return true;
	} 
}
enum length_units_t {kilometers, meters, centimeters, millimeters, miles, yards, feet, inches}; 
class Length: public Float {
	public:
	   Length(Float, string); 
	   Length(); 
	   length_units_t units;
	   string toString();
	   Length toMeters() const; 
	   Length toFeet(); 
	   Length toInches();
	   Length toYards(); 
	   Length toMiles();
	   Length toKilometers();
	   Length toCentimeters();
	   Length toMillimeters();
	   Length operator=(Float); 
	   Length operator=(Length); 
	   Length operator=(double); 
	   Length operator=(int);
	   bool operator==(Length); 
	   bool operator==(const double in) const { return Float::operator==(in); }
	   bool operator==(const int in)    const { return Float::operator==(in); }
	   bool operator==(const Float in)  const { return Float::operator==(in); } 

}; 
		
#endif 
